package nina.yiyou.attendance.s20sum.compute

import nina.yiyou.attendance.s20sum.input.AttendDetailCsvReader
import nina.yiyou.salary.output.util.KeyPrefixPrepender

import java.util.stream.Collectors

import static java.util.stream.Collectors.groupingBy

class AttendDetailSummarizer {

  AttendDetailSummarizer(List<AttendDetailCsvReader.Line> detailList) {
    _detailList = detailList
  }

  List<Map> sum() {
    return _detailList.stream()
        .collect(groupingBy { AttendDetailCsvReader.Line l -> l.employeeId() })
        .values().stream()
        .map { sumEmployee(it) }
        .collect(Collectors.toList())
  }

  /**
   * @see nina.yiyou.attendance.s20sum.output.DetailSumGenerator#makeTemplateKeys
   */
  private Map sumEmployee(List<AttendDetailCsvReader.Line> detailList) {
    def sumCol = { Closure<Number> c ->
      return detailList.stream()
          .mapToDouble { (c(it) ?: 0).toDouble() }
          .sum()
    }

    def countCol = { Closure<Number> c ->
      return detailList.stream()
          .map { c(it) }
          .filter { it instanceof Number }
          .filter { it > 0 }
          .count()
    }

//    def avgCol = { Closure<Number> c ->
//      return (sumCol(c) / countCol(c) as double).round(2)
//    }

    Map<String, ?> inputMap = detailList[0].inputMap()

    Map<String, Double> leaveMap = detailList.stream()
        .map { it.leaveMap() }
        .reduce([:], { s, e -> e.entrySet().each { s.merge(it.key, it.value, Double.&sum) }; s })

    //TODO: 免打卡天数（增加免打卡列）

    return inputMap + new KeyPrefixPrepender([
        '日历天数': detailList.size(),
        '打卡天数': countCol { AttendDetailCsvReader.Line l -> l.workingHour() },
        '试用应计': sumCol { AttendDetailCsvReader.Line l -> l.totalHourProba() },
        '试用实计': sumCol { AttendDetailCsvReader.Line l -> l.wageHourProba() },
        '转正应计': sumCol { AttendDetailCsvReader.Line l -> l.totalHourFull() },
        '转正实计': sumCol { AttendDetailCsvReader.Line l -> l.wageHourFull() },
        '工作时长': sumCol { AttendDetailCsvReader.Line l -> l.workingHour() },
        '获得调休': sumCol { AttendDetailCsvReader.Line l -> l.gainOff() },
        '迟到'  : sumCol { AttendDetailCsvReader.Line l -> l.lateCount() },
        '忘打卡' : sumCol { AttendDetailCsvReader.Line l -> l.forgotCount() },
        '加班'  : sumCol { AttendDetailCsvReader.Line l -> l.workOvertime() },
        '餐补'  : sumCol { AttendDetailCsvReader.Line l -> l.mealStipend() },
    ] + leaveMap, '计算2').prepend()
  }

  private final List<AttendDetailCsvReader.Line> _detailList
}
